<template>
    <Select
        :value="value"
        @input="handlerInput"
        filterable
        remote
        clearable
        :remote-method="noop"
        :loading="loading"
        :label="label"
        @on-query-change="handleQuery"
        @on-clear="handlerClear"
    >
        <Option
            v-for="(option, index) in options"
            :value="option.value"
            :key="index"
        >{{ option.label }}</Option>
    </Select>
</template>
<script>
import { debounce, trim } from '@/libs/tools'

function defFilterMethod ({ list }) {
    const value = this.valueKey
    const label = this.labelKey
    return list.map(item => {
        return {
            value: item[value],
            label: item[label]
        }
    })
}
export default {
    name: 'RemoteSelect',
    props: {
        label: {
            type: String,
            default: ''
        },
        value: {
            type: [String, Number, Array],
            default: ''
        },
        valueKey: {
            type: String,
            default: 'value'
        },
        labelKey: {
            type: String,
            default: 'label'
        },
        remoteFn: {
            type: Function
        },
        filterMethod: {
            type: Function,
            default: defFilterMethod
        }
    },
    data () {
        return {
            loading: false,
            options: []
        }
    },
    watch: {
        label (v) {
            this.handleQuery(v)
        }
    },
    created () {
        const { value, label = '' } = this
        if (value) {
            this.options = [{ value, label }]
        }
        if (label === '') {
            this.handleQuery('')
        }
    },
    methods: {
        noop () {},
        handlerClear () {
            this.$emit('input', '')
        },
        handlerInput (v) {
            this.$emit('input', v)
        },
        handleQuery: debounce(function (query) {
            query = trim(query)
            if (query || this._list === undefined) {
                if (this.options.findIndex(item => item.label && item.label === query) >= 0) return
                this.loading = true
                this.remoteFn(query)
                    .then(res => {
                        if (res.data.code === '0000') {
                            this.options = this.filterMethod(res.data.data)
                            if (!query && this.options.length) {
                                this._list = this.options.slice()
                            }
                        } else {
                            this.options = []
                        }
                        this.loading = false
                        return res
                    })
                    .catch(err => {
                        this.options = []
                        this.loading = false
                    })
            } else {
                this.options = this._list.slice()
            }
        }, 200)
    }
}
</script>
